package com.cgly.medical.service.impl;

import com.alibaba.fastjson.JSON;
import com.cgly.medical.constants.MqConstants;
import com.cgly.medical.domain.DrugCompany;
import com.cgly.medical.domain.Patient;
import com.cgly.medical.mapper.PatientMapper;
import com.cgly.medical.model.PatientModel;
import com.cgly.medical.service.PatientService;
import com.cgly.medical.util.Msg;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PatientServiceImpl implements PatientService {

    @Resource
    PatientMapper patientMapper;

    @Resource
    private RestHighLevelClient client;

    @Resource
    private RabbitTemplate rabbitTemplate;

    ////查询所有的患者信息
    @Override
    public Msg getAllPatient(Integer page,Integer limit) {
        PageHelper.startPage(page,limit);
        List<Patient> patientList = patientMapper.getAllPatient();
        if(patientList.size()==0){
            return Msg.fail().mess("患者信息查询失败");
        }else{
            PageInfo<Patient> allPatient=new PageInfo<>(patientList,5);
            return Msg.success().data("allPatient",allPatient);
        }
    }

    @Override
    public Msg getSomePatient(Patient patient) {
        PageHelper.startPage(patient.getPn(),patient.getSize());
         List<Patient> patientList = patientMapper.getSomePatient(patient);
         if(patientList.size()==0){
             return Msg.fail().mess("无此患者信息");
         }else{
             PageInfo<Patient> allPatient=new PageInfo<>(patientList,5);
             return Msg.success().data("allPatient",allPatient);
         }
    }

    @Override
    public Msg deletePatientById(Integer id) {
        int row = patientMapper.deletePatientById(id);
        if(row==0){
            return Msg.fail().mess("患者信息删除失败");
        }else {
            rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_DELETE_KEY, id);
            return Msg.success().data("row",row);
        }

    }

    @Override
    public Msg updatePatient(Patient patient) {
         int row = patientMapper.updatePatient(patient);
        if(row==0){
            return Msg.fail().mess("患者信息更新失败");
        }else {
            rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_INSERT_KEY, patient.getId());
            return Msg.success().data("row",row);
        }

    }

    @Override
    public Msg insertPatient(Patient patient) {
        patient.setEnterTime(patient.getEnterTime().replace("T"," "));
        patient.setEnterTime(patient.getEnterTime().replace(".000Z",""));
        patient.setOutTime(patient.getOutTime().replace("T"," "));
        patient.setOutTime(patient.getOutTime().replace(".000Z",""));
        int row = patientMapper.insertPatient(patient);
        if(row==0){
            return Msg.fail().mess("添加患者信息失败");
        }else {
            int maxId = getMaxId();
            rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_INSERT_KEY, maxId);
            return Msg.success().data("row",row);
        }
    }

//    @Override
//    public Msg addOrUpdatePatient(Patient patient) {
//        List<Patient> somePatient = patientMapper.getSomePatient(patient);
//        if(somePatient.size()!=0){
//            patientMapper.updatePatient(patient);
//            return Msg.success().data("patient",somePatient.get(0));
//        }else{
//            patientMapper.insertPatient(somePatient.get(0));
//            int maxId = patientMapper.getMaxId();
//            Patient patientById = patientMapper.getPatientById(maxId);
//            return Msg.success().data("patient",patientById);
//        }
//    }

    @Override
    public Msg getPatientById(Integer id) {
        Patient patient = patientMapper.getPatientById(id);
        if(patient==null){
            return Msg.fail().mess("查询患者信息失败");
        }else{
            return Msg.success().data("patient",patient);
        }
    }

    @Override
    public Msg addOrUpdatePatient(Patient patient) {
        List<Patient> somePatient = patientMapper.getSomePatient(patient);
        Date date=new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sdf.format(date);
        if(somePatient.size()!=0){
            patient.setOutTime(format);
            patientMapper.updatePatient(patient);
            rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_INSERT_KEY, patient.getId());
            return Msg.success().data("patients",somePatient.get(0));
        }else{

            patient.setOutTime(format);
            patient.setEnterTime(format);
            patientMapper.insertPatient(patient);
            int maxId = patientMapper.getMaxId();
            rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_INSERT_KEY, maxId);
            Patient patientById = patientMapper.getPatientById(maxId);
            System.out.println("qqqqqqqqqqqq"+patientById);
            return Msg.success().data("patients",patientById);
        }
    }


    @Override
    public Msg getSuggestions(String prefix) {
        try {
            //1.准备request
            SearchRequest request=new SearchRequest("hotel");
            //2.准备DSL
            request.source().suggest(new SuggestBuilder().addSuggestion("" +
                            "suggestions"
                    , SuggestBuilders.completionSuggestion("suggestion")
                            .prefix(prefix)
                            .skipDuplicates(true)
                            .size(10)));
            //3.发起请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //4.解析结果
            Suggest suggest = response.getSuggest();
            //4.1 根据补全查询名称，获取补全结果
            CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
            //4.2 获取options
            List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
            //4.3 遍历
            List<String> list=new ArrayList<>(options.size());
            for(CompletionSuggestion.Entry.Option option:options){
                String text = option.getText().toString();
                list.add(text);
            }
            return Msg.success().data("suggestionList",list);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //高亮显示
    @Override
    public Msg highlightShow(Patient patient) {
        try {
            //1.准备request
            SearchRequest request = new SearchRequest("patient");
            //2.准备DSL
            //2.1 query
            request.source().query(QueryBuilders.matchQuery("pname",patient.getPname()));
            //2.2 高亮
            request.source().highlighter(new HighlightBuilder().field("pname").requireFieldMatch(false));
            //3.发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //4.解析响应
            List<PatientModel> list = handleResponse(response);
//            int total=list.size();
//            PageHelper.startPage(patient.getPn(),patient.getSize());
//            List<PatientModel> list1 = handleResponse(response);
//            PageInfo<PatientModel> allPatient=new PageInfo<>(list1,5);
//            allPatient.setTotal(total);
            List<PatientModel> subList = list.stream().skip((patient.getPn()-1)*patient.getSize()).limit(patient.getSize()).
                    collect(Collectors.toList());
            return Msg.success().data("allPatient",subList).data("total",list.size());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteById(Integer id) {
        try {
            DeleteRequest request=new DeleteRequest("patient",id.toString());
            client.delete(request,RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void insertById(Integer id) {
        try {
            //0.根据id查询酒店数据
            Patient patient = patientMapper.getPatientById(id);
            //转换为文档类型
            PatientModel patientModel=new PatientModel(patient);
            //1.准备request对象
            IndexRequest request = new IndexRequest("patient").id(String.valueOf(patientModel.getId()));
            //2.准备json文档
            request.source(JSON.toJSONString(patientModel), XContentType.JSON);
            //3.发送请求
            client.index(request,RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int getMaxId() {
        int maxId = patientMapper.getMaxId();
        return maxId;
    }


    //抽取方法，解析response
    private List<PatientModel> handleResponse(SearchResponse response) {
        List<PatientModel> list=new ArrayList<>();
        SearchHits searchHits= response.getHits();
        //4.1获取总条数
        long total =searchHits.getTotalHits().value;
        System.out.println("总共搜索到："+total+"条数据");
        //4.2文档数组
        SearchHit[] hits=searchHits.getHits();
        //4.3遍历
        for(SearchHit hit:hits){
            //获取文档source
            String json=hit.getSourceAsString();
            //反序列化
            PatientModel patientModel= JSON.parseObject(json,PatientModel.class);
            //获取高亮结果
            Map<String, HighlightField> highlightFields=hit.getHighlightFields();
            if(!CollectionUtils.isEmpty(highlightFields)){
                //根据字段名获取高亮结果
                HighlightField highlightField = highlightFields.get("pname");
                if(highlightField!=null){
                    //获取高亮值
                    String name = highlightField.getFragments()[0].string();
                    //覆盖非高亮结果
                    patientModel.setPname(name);
                }
            }
            patientModel.setPname(patientModel.getPname().replaceAll("<em>","<span style=\"background- color: #FFFF00;\">"));
            patientModel.setPname(patientModel.getPname().replaceAll("</em>","</span>"));
            System.out.println("patientModel= "+patientModel);
            list.add(patientModel);
        }
        return list;
    }
}
